/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020.
 * Description: set flags
 * Author: yanbo <joey.yanbo@huawei.com>
 * Create: 2020-01-19
 */
#include <linux/types.h>
#include <linux/libfdt.h>
#include <mach/slave_core.h>
#include "flag_cmdline.h"

#if defined(CONFIG_KASAN) && defined(memset)
#undef memset
#endif

struct flag_info {
	char *name;
};

struct flag_info bootargs_flag_info[NUM_OF_BOOTARGS_FLAGS];

static void set_flag(unsigned int *flag, int bit_position, int flag_len)
{
	int offset = bit_position / BITS_PER_INT;
	unsigned int mask = (1 << (unsigned int)(bit_position % BITS_PER_INT));

	if (bit_position >= (flag_len * BITS_PER_INT))
		return;

	flag[offset] |= mask;
}

static void init_bootargs_flag_info(void)
{
	bootargs_flag_info[BIT_SET_IBE].name = "set_IBE";
}

static void set_bootargs_flag(const char *bootargs, unsigned int *flag, int flag_len)
{
	int i;
	int bootargs_flag_info_count = NUM_OF_BOOTARGS_FLAGS;

	for (i = 0; i < bootargs_flag_info_count; i++) {
		if (match_str_in_bootargs(bootargs, bootargs_flag_info[i].name))
			set_flag(flag, i, flag_len);
	}
}

static void check_bootargs_flag(const void *dtb_address, unsigned int *flag, int flag_len)
{
	int node;
	unsigned int size;
	char *bootargs = NULL;

	node = fdt_subnode_offset(dtb_address, 0, "chosen");
	if (node < 0)
		return;

	bootargs = (char *)fdt_getprop(dtb_address, node, "bootargs", &size);
	if (!bootargs)
		return;

	init_bootargs_flag_info();
	set_bootargs_flag(bootargs, flag, flag_len);
}

static void save_flag(unsigned int *memory_addr, unsigned int *flag, int size)
{
	memcpy(memory_addr, flag, size);
}

void check_rtos_flag(const void *dtb_address, unsigned char *image_addr)
{
	unsigned int flag[RTOS_FLAG_ARRAY_LEN];
	unsigned int *base = NULL;
	uintptr_t tmp;

	tmp = ((uintptr_t)image_addr >> ALIGE_1M_SHIFT) << ALIGE_1M_SHIFT;
	tmp += HISI_FLAG_OFFSET;
	base = (unsigned int *)tmp;

	memset(flag, 0, sizeof(flag));

	check_bootargs_flag(dtb_address, flag, RTOS_FLAG_ARRAY_LEN);

	save_flag(base, flag, sizeof(flag));
}
